package com.navinfo.platform.trip.common.arithmetic;

import com.navinfo.platform.trip.common.arithmetic.data.CommonData;
import com.navinfo.platform.trip.common.arithmetic.data.OuterEventData;
import com.navinfo.platform.trip.common.arithmetic.data.OuterStatisticData;
import com.navinfo.platform.trip.common.arithmetic.enums.EventStatus;
import com.navinfo.platform.trip.common.arithmetic.enums.EventType;
import com.navinfo.platform.trip.common.arithmetic.manager.AbstractArithmetic;
import com.navinfo.platform.trip.common.arithmetic.manager.EventConvert;
import com.navinfo.platform.trip.common.arithmetic.var.VarCoastNeutralGear;
import com.navinfo.platform.trip.common.config.ConfigMap;
import com.navinfo.platform.trip.common.util.ArithmeticUtils;

import java.util.Optional;

/**
 * 东风空挡滑行算法<br/>
 * 依赖{@link Mileage}里程油耗算法<br/>
 * 输出：统计、事件<br/>
 * @author web
 */
public class CoastNeutralGear_DF extends AbstractArithmetic<VarCoastNeutralGear> {
    /**
     * 东风空挡滑行事件
     */
    private final EventType eventType = EventType.coastNeutralGear_DF;
    /**
     * 转速阀值 单位：RPM
     */
    private int rotationMin = ConfigMap.getInteger("DF_IdlingSlide_Rotation_Min");
    /**
     * 转速阀值 单位：RPM
     */
    private int rotationMax = ConfigMap.getInteger("DF_IdlingSlide_Rotation_Max");
    /**
     * 速度阀值 单位：km/h
     */
    private int speedThreshold = ConfigMap.getInteger("DF_IdlingSlide_Speed_Threshold");
    /**
     * 时长阀值 单位：ms
     */
    private int timeThreshold = ConfigMap.getInteger("DF_IdlingSlide_Time_Threshold");

    /**
     * 判断当前点是否为东风空挡滑行状态
     */
    boolean isCurrentIdlingSlide() {
        CommonData data = getCommonData();
        return data.getRotation()>=rotationMin && data.getRotation()<=rotationMax && data.getSpeedKmh()>speedThreshold;
    }

    @Override
    public void calculate() {
        logger.debug("进入东风空挡滑行算法.[terminalId:{}]", terminalId);
        VarCoastNeutralGear var = getObj();
        boolean previousIdle = var.isPreNeutralSlide();
        boolean currentIdle = isCurrentIdlingSlide();
        logger.debug("东风空挡滑行算法，东风空挡滑行状态：previousIdle:{},currentIdle:{}.[terminalId:{}]", previousIdle, currentIdle, terminalId);

        //算法计算
        switch (getEventStatus(previousIdle, currentIdle)) {
            case START:
                logger.debug("东风空挡滑行算法，事件开始.[terminalId:{}]", terminalId);
                startEventData(eventType);
                break;
            case IN:
                logger.debug("东风空挡滑行算法，事件中.[terminalId:{}]", terminalId);
                calcEventData(eventType);
                break;
            case END:
                logger.debug("东风空挡滑行算法，事件结束.[terminalId:{}]", terminalId);
                calcEventData(eventType);
                endEvent();
                break;
            default:
                logger.debug("东风空挡滑行算法，东风空挡滑行状态：上一次和本次都未东风空挡滑行，不进行计算.[terminalId:{}]", terminalId);
        }

        //行程结束时要清理对应的未结束事件
        if (getCommonData().isTripLastNode()) {
            endEvent();
        }

        var.setPreNeutralSlide(currentIdle);
        logger.debug("东风空挡滑行算法结束.[terminalId:{}]", terminalId);
    }

    @Override
    public void collect(OuterStatisticData statisticDataOut) {
        VarCoastNeutralGear var = getObj();
        statisticDataOut.setNeutralGearCoastMileage_DF(ArithmeticUtils.mileageMToM(var.getMileage()));
        statisticDataOut.setNeutralGearCoastFuel_DF(ArithmeticUtils.fuelMlToMl(var.getFuel()));
        statisticDataOut.setNeutralGearCoastDuration_DF(ArithmeticUtils.timeMsToSecond(var.getDuration()));
        statisticDataOut.setNeutralGearCoastNumber_DF(var.getNumber());
    }

    /**
     * 累加事件信息
     */
    @Override
    protected void calcEventData(EventType eventType) {
        Optional.ofNullable(drivingData.getEventData(eventType)).ifPresent(eventData -> {
            EventConvert.convertCommonField(eventData, drivingData);
            if (getCommonData().getGpsTime()-eventData.getStartGpsTime() >= timeThreshold) {
                // 满足时长阈值后，设置事件的结束状态
                eventData.setStatus(EventStatus.END.getValue());
            }
        });
    }

    /**
     * 事件结束处理
     */
    private void endEvent() {
        Optional.ofNullable(drivingData.getEventData(eventType)).ifPresent(eventData -> {
            EventConvert.convertEnd(eventData, drivingData);
            drivingData.removeEventData(eventType);

            if (Optional.ofNullable(eventData.getDuration()).orElse(0L) >= timeThreshold) {
                logger.debug("东风空挡滑行时间{}ms,进行统计", Optional.ofNullable(eventData.getDuration()).orElse(0L));

                //事件结束，统计里程、油耗、时长、次数加1
                eventDataToVar(eventData);

                //放入输出事件列表
                drivingData.addEventDataToList(eventData);
            } else {
                logger.debug("东风空挡滑行时间{}ms,小于阈值{}ms，不进行统计", Optional.ofNullable(eventData.getDuration()).orElse(0L), timeThreshold);
            }
        });
    }

    /**
     * 事件数据赋值到统计数据中
     * @param eventData
     */
    private void eventDataToVar(OuterEventData eventData){
        VarCoastNeutralGear var = getObj();
        var.addNumber(1);
        var.addMileage( Optional.ofNullable(eventData.getExtendField05()).orElse(0.0));
        var.addFuel( Optional.ofNullable(eventData.getExtendField06()).orElse(0.0));
        var.addDuration(Optional.ofNullable(eventData.getDuration()).orElse(0L).intValue());
    }
}
